package tools

import (
	"os"

	// 为两个 zap 包设置明确的别名
	microzap "github.com/micro/plugins/v5/logger/zap" // 别名 microzap
	"go-micro.dev/v5/logger"
	"go-micro.dev/v5/server"
	uberzap "go.uber.org/zap" // 别名 uberzap
	"go.uber.org/zap/zapcore"
	"google.golang.org/grpc/grpclog"
	"gopkg.in/natefinch/lumberjack.v2"
)

var Zaplog logger.Logger

// ZapGrpcLogger 完整实现 grpclog.LoggerV2 接口
type ZapGrpcLogger struct {
	Logger *uberzap.SugaredLogger
}

// 实现所有必需的方法
func (l *ZapGrpcLogger) Info(args ...interface{}) {
	l.Logger.Info(args...)
}

func (l *ZapGrpcLogger) Infoln(args ...interface{}) {
	l.Logger.Info(args...)
}

func (l *ZapGrpcLogger) Infof(format string, args ...interface{}) {
	l.Logger.Infof(format, args...)
}

func (l *ZapGrpcLogger) Warning(args ...interface{}) {
	l.Logger.Warn(args...)
}

func (l *ZapGrpcLogger) Warningln(args ...interface{}) {
	l.Logger.Warn(args...)
}

func (l *ZapGrpcLogger) Warningf(format string, args ...interface{}) {
	l.Logger.Warnf(format, args...)
}

func (l *ZapGrpcLogger) Error(args ...interface{}) {
	l.Logger.Error(args...)
}

func (l *ZapGrpcLogger) Errorln(args ...interface{}) {
	l.Logger.Error(args...)
}

func (l *ZapGrpcLogger) Errorf(format string, args ...interface{}) {
	l.Logger.Errorf(format, args...)
}

func (l *ZapGrpcLogger) Fatal(args ...interface{}) {
	l.Logger.Fatal(args...)
}

func (l *ZapGrpcLogger) Fatalln(args ...interface{}) {
	l.Logger.Fatal(args...)
}

func (l *ZapGrpcLogger) Fatalf(format string, args ...interface{}) {
	l.Logger.Fatalf(format, args...)
}

func (l *ZapGrpcLogger) V(level int) bool {
	// 简单实现，实际中可根据level判断
	return l.Logger.Desugar().Core().Enabled(uberzap.ErrorLevel)
}

/**
 * @description 初始化日志记录器（使用别名 uberzap）
 * @author huwl
 * @date 2025/08/06 21:32:29
 */
func InitZapLogger(serviceName string) *uberzap.Logger {
	// 1. 创建日志级别编码器
	encoderConfig := uberzap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	jsonEncoder := zapcore.NewJSONEncoder(encoderConfig)

	// 2. 创建输出目标
	outputs := []zapcore.WriteSyncer{}
	outputs = append(outputs, zapcore.AddSync(os.Stdout))

	// 文件输出（带切割）
	logPath := "logs"
	fileOutput := zapcore.AddSync(&lumberjack.Logger{
		Filename:   logPath + "/" + serviceName + ".log",
		MaxSize:    ZapLoggerMaxSize,    // MB
		MaxBackups: ZapLoggerMaxBackups, // 保留旧日志文件数量
		MaxAge:     ZapLoggerMaxAge,     // 保留天数
		Compress:   ZapLoggerCompress,   // 压缩旧日志
		LocalTime:  true,                // 使用本地时间
	})
	outputs = append(outputs, fileOutput)

	// 3. 设置日志级别
	logLevel := uberzap.InfoLevel
	switch LogLevel {
	case "debug":
		logLevel = uberzap.DebugLevel
	case "warn":
		logLevel = uberzap.WarnLevel
	case "error":
		logLevel = uberzap.ErrorLevel
	}

	// 4. 创建核心
	core := zapcore.NewCore(
		jsonEncoder,
		zapcore.NewMultiWriteSyncer(outputs...),
		logLevel,
	)

	// 5. 创建带选项的 Logger
	return uberzap.New(core,
		uberzap.AddCaller(),
		uberzap.AddCallerSkip(1),
		uberzap.AddStacktrace(uberzap.ErrorLevel),
		uberzap.Fields(uberzap.String("service", serviceName)),
	)
}

/**
 * @description 替换 Go-Micro 内部日志系统（使用别名 microzap）
 * @author huwl
 * @date 2025/08/06 21:32:07
 */
func ReplaceMicroLoggers(zapLogger *uberzap.Logger, grpcLogger grpclog.LoggerV2) {
	// 1. 创建Go-Micro的Zap适配器
	microLogger, _ := microzap.NewLogger(
		microzap.WithLogger(zapLogger),
	)

	// 2. 替换Go-Micro默认日志
	logger.DefaultLogger = microLogger

	// 3. 替换gRPC日志
	grpclog.SetLoggerV2(grpcLogger)

	// 4. 替换默认服务器的日志器
	server.DefaultServer.Init(server.WithLogger(microLogger))
}
